﻿using AnesSystem.Controls;
using AnesSystem.Models;
using AnesSystem.Util;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;

namespace AnesSystem.ViewModels
{
    public class PacuRealTimeSignShowCtrlViewModel : MultitonBaseViewModel
    {
        #region Variables
        /// <summary>
        /// 所有生命体征
        /// </summary>
        private ObservableCollection<List<PatientVitalSignsModel>> _vitalList;
        private ObservableCollection<CustomItemControl> _vitalCtrlList;
        /// <summary>
        /// 折线图生命体征
        /// </summary>
        private ObservableCollection<List<PatientVitalSignsModel>> _lineVitalList;
        private List<PatientVitalSignsModel> _allVitalList;
        /// <summary>
        /// 表格生命体征
        /// </summary>
        private ObservableCollection<List<PatientVitalSignsModel>> _tableVitalList;
        private ObservableCollection<string> _timeItems;
        private List<PatientVitalSignsModel> _timeList;

        private Dictionary<int, Dictionary<string, List<PatientVitalSignsModel>>> _dicAllVital;

        #endregion


        #region Constructor

        public PacuRealTimeSignShowCtrlViewModel(int page)
        {
            CurPage = page;
            _vitalList = new ObservableCollection<List<PatientVitalSignsModel>>();
            _timeItems = new ObservableCollection<string>();
            _vitalCtrlList = new ObservableCollection<CustomItemControl>();
            _lineVitalList = new ObservableCollection<List<PatientVitalSignsModel>>();
            _tableVitalList = new ObservableCollection<List<PatientVitalSignsModel>>();
            _allVitalList = new List<PatientVitalSignsModel>();
            _dicAllVital = new Dictionary<int, Dictionary<string, List<PatientVitalSignsModel>>>();
        }

        #endregion


        #region Properties

        public ObservableCollection<List<PatientVitalSignsModel>> VitalList
        {
            get
            {
                return _vitalList;
            }

            set
            {
                _vitalList = value;
            }
        }

        public ObservableCollection<string> TimeItems
        {
            get
            {
                return _timeItems;
            }

            set
            {
                _timeItems = value;
            }
        }

        public List<PatientVitalSignsModel> TimeList
        {
            get
            {
                return _timeList;
            }

            set
            {
                _timeList = value;
            }
        }

        public ObservableCollection<CustomItemControl> VitalCtrlList
        {
            get
            {
                return _vitalCtrlList;
            }

            set
            {
                _vitalCtrlList = value;
            }
        }

        public BaseVitalCellCtrl FocusElement { get; set; }

        public ObservableCollection<List<PatientVitalSignsModel>> LineVitalList
        {
            get
            {
                return _lineVitalList;
            }

            set
            {
                _lineVitalList = value;
            }
        }

        public ObservableCollection<List<PatientVitalSignsModel>> TableVitalList
        {
            get
            {
                return _tableVitalList;
            }

            set
            {
                _tableVitalList = value;
            }
        }

        public List<PatientVitalSignsModel> AllVitalList
        {
            get
            {
                return _allVitalList;
            }

            set
            {
                _allVitalList = value;
            }
        }

        public Dictionary<int, Dictionary<string, List<PatientVitalSignsModel>>> DicAllVital
        {
            get
            {
                return _dicAllVital;
            }
        }

        public PatientVitalSignsModel SelectedVitalModel { get; set; }

        #endregion


        #region 依赖属性


        #endregion


        #region Event


        #endregion


        #region PrivateMethods


        public void InitialVitalCtrlList()
        {
            VitalCtrlList.Clear();
            for (int i = 0; i < _vitalList.Count; i++)
            {
                VitalCtrlList.Add(CreateVitalCtrl(_vitalList[i]));
            }
        }

        private void LeftMove()
        {
            if (FocusElement.CellIndex == 0) return;
            Visual f = VitalCtrlList[FocusElement.RowIndex].ItemsSource[FocusElement.CellIndex - 1];
            SetFocus(f);
        }
        private void RightMove()
        {
            if (FocusElement.CellIndex >= 47) return;
            Visual f = VitalCtrlList[FocusElement.RowIndex].ItemsSource[FocusElement.CellIndex + 1];
            SetFocus(f);
        }
        private void UpMove()
        {
            if (FocusElement.RowIndex == 0) return;
            CustomItemControl cic = VitalCtrlList[FocusElement.RowIndex - 1];
            Visual f = cic.ItemsSource[FocusElement.CellIndex];
            string value = "";
            value = cic.SerchNearValue(FocusElement.CellIndex); ;
            SetFocus(f, value, true);

        }

        private void DownMove()
        {
            if (FocusElement.RowIndex == VitalCtrlList.Count - 1) return;
            CustomItemControl cic = VitalCtrlList[FocusElement.RowIndex + 1];
            Visual f = cic.ItemsSource[FocusElement.CellIndex];
            string value = cic.SerchNearValue(FocusElement.CellIndex);
            SetFocus(f, value, true);
        }

        private void SetFocus(Visual f, string value = "", bool isUpOrDown = false)
        {
            if (f != null)
            {
                BaseVitalCellCtrl ctrl = (BaseVitalCellCtrl)f;
                PatientVitalSignsModel pm = ctrl.DataContext as PatientVitalSignsModel;

                if (isUpOrDown && string.IsNullOrEmpty(pm.ModValue))
                {
                    pm.ModValue = value;
                }
                else if (string.IsNullOrEmpty(pm.ModValue) && !isUpOrDown)
                {
                    pm.ModValue = (FocusElement.DataContext as PatientVitalSignsModel).ModValue;
                }

                ctrl.SetFocus();
            }
        }

        private void InitTimeItem()
        {
            TimeItems.Clear();
            DateTime pacuRecordSignTime = DataManager.Instance.CurrentPatientLink.Status.PacuStartTime;
            DateTime startTime = pacuRecordSignTime.AddHours((CurPage - 1) * 4);
            string showDateHM = startTime.ToString(DateFormat.DATE_FORMAT_STR_HM);
            TimeItems.Add(showDateHM);
            DateTime date = startTime;
            for (int i = 0; i < 48; i++)
            {
                date = date.AddMinutes(5);
                TimeItems.Add(date.ToString(DateFormat.DATE_FORMAT_STR_HM));
            }
            _timeList = new List<PatientVitalSignsModel>();

            foreach (var item in TimeItems)
            {
                PatientVitalSignsModel p = new PatientVitalSignsModel();
                p.ModValue = item;
                p.Code = "TIME_CODE";
                _timeList.Add(p);
            }
        }

        private void InitVitalData()
        {
            VitalList.Clear();
            LineVitalList.Clear();
            TableVitalList.Clear();

            DateTime pacuRecordSignTime = DataManager.Instance.CurrentPatientLink.Status.PacuStartTime;
            DateTime startTime = pacuRecordSignTime.AddHours((CurPage - 1) * 4);
            DateTime endTime = startTime.AddHours(4);

            VitalList.Add(_timeList);

            #region 分开加载生命体征

            //加载折线图数据
            //foreach (var item in OperationDataPool.Instance.CurOperationData.VitalSignDataCache.BesideLineObservableList)
            //{
            //    LineVitalList.Add(item.Values.ToList());
            //}
            //_dicAllVital.Clear();
            //Dictionary<string, List<PatientVitalSignsModel>> dic1 = new Dictionary<string, List<PatientVitalSignsModel>>();
            //for (int i = 0; i < LineVitalList.Count; i++)
            //{
            //    List<PatientVitalSignsModel> pvmList = new List<PatientVitalSignsModel>();
            //    string code = "";
            //    for (int j = 0; j < LineVitalList[i].Count; j++)
            //    {
            //        PatientVitalSignsModel pvm = LineVitalList[i][j];
            //        if (!(pvm.CaptureTime.CompareTo(startTime) < 0 || pvm.CaptureTime.CompareTo(endTime) > 0))
            //        {
            //            pvmList.Add(pvm);
            //            code = pvm.Code;
            //        }
            //    }
            //    LineVitalList[i].Clear();
            //    LineVitalList[i].AddRange(pvmList);
            //    dic1.Add(code, pvmList);
            //}
            //_dicAllVital.Add(0, dic1);

            ////加载表格数据
            //foreach (var item in OperationDataPool.Instance.CurOperationData.VitalSignDataCache.BesideTableObservableList)
            //{
            //    TableVitalList.Add(item.Values.ToList());
            //}
            //Dictionary<string, List<PatientVitalSignsModel>> dic2 = new Dictionary<string, List<PatientVitalSignsModel>>();

            //for (int i = 0; i < TableVitalList.Count; i++)
            //{
            //    List<PatientVitalSignsModel> pvmList = new List<PatientVitalSignsModel>();
            //    string code = "";
            //    for (int j = 0; j < TableVitalList[i].Count; j++)
            //    {
            //        PatientVitalSignsModel pvm = TableVitalList[i][j];
            //        if (!(pvm.CaptureTime.CompareTo(startTime) < 0 || pvm.CaptureTime.CompareTo(endTime) > 0))
            //        {
            //            pvmList.Add(pvm);
            //            code = pvm.Code;
            //        }

            //    }
            //    TableVitalList[i].Clear();
            //    TableVitalList[i].AddRange(pvmList);
            //    dic2.Add(code, pvmList);
            //}

            #endregion

            foreach (var item in OperationDataPool.Instance.CurOperationData.VitalSignDataCacheDic[Constants.ISPACU].BedsideMapMap.Values.ToList())
            {
                if (item.Values.ToList()==null)
                {
                    continue;
                }
                VitalList.Add(item.Values.ToList());
            }
            AllVitalList.Clear();
            for (int i = 1; i < VitalList.Count; i++)
            {
                List<PatientVitalSignsModel> pvmList = new List<PatientVitalSignsModel>();
                for (int j = 0; j < VitalList[i].Count; j++)
                {
                    PatientVitalSignsModel pvm = VitalList[i][j];
                    if (!(pvm.CaptureTime.CompareTo(startTime) < 0 || pvm.CaptureTime.CompareTo(endTime) > 0))
                    {
                        pvmList.Add(pvm);
                    }

                }
                VitalList[i].Clear();
                VitalList[i].AddRange(pvmList);
                AllVitalList.AddRange(pvmList);
            }
        }

        private CustomItemControl CreateVitalCtrl(List<PatientVitalSignsModel> vitalList)
        {
            List<FrameworkElement> list = new List<FrameworkElement>();
            List<PatientVitalSignsModel> vitals = vitalList;
            int totalRows = VitalCtrlList.Count;
            int count = vitals.Count;
            for (int j = 0; j < count; j++)
            {

                PatientVitalSignsModel model = vitals[j];
                BaseVitalCellCtrl ctrl;
                if (model.Code.ToLower().Equals("param_ecg"))
                {
                    ctrl = new ECGDropDownListCtrl();
                }
                else if (model.Code.ToLower().Equals("param_i:e"))
                {
                    ctrl = new IEDropDownListCtrl();
                }
                else
                {
                    ctrl = new ParamerterCellCtrl();
                }

                if (totalRows % 2 == 0)
                {
                    ctrl.Background = RealTimeSignShowUtil.EVENROWBACKGROUND;

                }
                else
                {
                    ctrl.Background = RealTimeSignShowUtil.UNEVENROWBACKGROUND; ;
                }

                ctrl.PreviewKeyDown += Ctrl_PreviewKeyDown;
                ctrl.PreviewKeyUp += Ctrl_PreviewKeyUp;
                ctrl.GotFocus += Ctrl_GotFocus;
                ctrl.PreviewMouseLeftButtonDown += Ctrl_PreviewMouseLeftButtonDown;
                ctrl.DataContext = model;
                ctrl.SelfVital = model;
                ctrl.CellIndex = j;
                ctrl.RowIndex = totalRows;
                PatientVitalSignsModel pvm = _vitalList[totalRows][j];
                ctrl.SetBinding(BaseVitalCellCtrl.ValueProperty, new Binding("ModValue")
                {
                    Source = pvm,
                    Mode = BindingMode.TwoWay,
                    UpdateSourceTrigger = UpdateSourceTrigger.LostFocus
                });
                ctrl.IsReadOnly = "TIME_CODE".Equals(pvm.Code) ? true : false;
                ctrl.Width = RealTimeSignShowUtil.CELLWIDTH;
                list.Add(ctrl);
            }
            CustomItemControl cic = new CustomItemControl();
            cic.Tag = vitalList[0];
            cic.Height = 35;
            cic.ItemsSource = list;
            return cic;
        }
        private void UpdateVitalCtrl()
        {
            for (int i = 0; i < VitalCtrlList.Count; i++)
            {
                List<FrameworkElement> list = VitalCtrlList[i].ItemsSource;
                for (int j = 0; j < list.Count; j++)
                {
                    BaseVitalCellCtrl ctrl = (BaseVitalCellCtrl)list[j];
                    ctrl.CellIndex = j;
                    ctrl.RowIndex = i;
                    if (i % 2 == 0)
                    {
                        ctrl.Background = RealTimeSignShowUtil.EVENROWBACKGROUND;

                    }
                    else
                    {
                        ctrl.Background = RealTimeSignShowUtil.UNEVENROWBACKGROUND; ;
                    }
                }
            }
        }


        private void SetParamerterCellCtrlValue(BaseVitalCellCtrl ctrl)
        {
            PatientVitalSignsModel model = ctrl.DataContext as PatientVitalSignsModel;
            if (!string.IsNullOrEmpty(model.ModValue)) return;
            model.ModValue = VitalCtrlList[ctrl.RowIndex].SerchNearValue(ctrl.CellIndex);
        }
        private void AddAllVitalList(List<PatientVitalSignsModel> list)
        {

            AllVitalList.AddRange(list);
        }

        #endregion


        #region Public/ProtectedMethods

        public void SetCellFocus(Key inputKey, KeyEventArgs e)
        {
            switch (inputKey)
            {
                case Key.Up:
                    UpMove();
                    e.Handled = true;
                    break;
                case Key.Down:
                    DownMove();
                    e.Handled = true;
                    break;
                case Key.Left:
                    LeftMove();
                    e.Handled = true;
                    break;
                case Key.Right:
                    RightMove();
                    e.Handled = true;
                    break;
                case Key.Enter:
                    RightMove();
                    e.Handled = true;
                    break;
                case Key.Tab:
                    RightMove();
                    e.Handled = true;
                    break;
            }

        }
        public void AddShowSigns(ConfigVitalSignsModel configVitalSignsModel)
        {
            List<PatientVitalSignsModel> curPageVitalList = GetCurPageVitals(OperationDataPool.Instance.CurOperationData.VitalSignDataCache.BedsideMapMap[configVitalSignsModel.code].Values.ToList());
            VitalList.Add(curPageVitalList);
            AddAllVitalList(curPageVitalList);
            VitalCtrlList.Add(CreateVitalCtrl(curPageVitalList));

        }

        private List<PatientVitalSignsModel> GetCurPageVitals(List<PatientVitalSignsModel> list)
        {
            DateTime pacuRecordSignTime = DataManager.Instance.CurrentPatientLink.Status.PacuStartTime;
            DateTime startTime = pacuRecordSignTime.AddHours((CurPage - 1) * 4);
            DateTime endTime = startTime.AddHours(4);
            List<PatientVitalSignsModel> curPageVitalList = new List<PatientVitalSignsModel>();
            foreach (var item in list)
            {
                if (item.CaptureTime >= startTime && item.CaptureTime <= endTime)
                {
                    curPageVitalList.Add(item);
                }
            }
            return curPageVitalList;
        }

        public void RemoveShowSigns(ConfigVitalSignsModel configVitalSignsModel)
        {
            for (int i = VitalList.Count - 1; i >= 0; i--)
            {
                if (VitalList[i][0].Code.Equals(configVitalSignsModel.code))
                {
                    VitalList.RemoveAt(i);
                }
            }
            for (int k = VitalCtrlList.Count - 1; k >= 0; k--)
            {
                if (((PatientVitalSignsModel)(VitalCtrlList[k].Tag)).Code.Equals(configVitalSignsModel.code))
                {
                    VitalCtrlList.RemoveAt(k);
                }
            }

            for (int j = AllVitalList.Count - 1; j >= 0; j--)
            {
                if (AllVitalList[j].Code.Equals(configVitalSignsModel.code))
                {
                    AllVitalList.RemoveAt(j);
                }
            }
            UpdateVitalCtrl();

        }

        public override void InitData()
        {
            InitTimeItem();
            InitVitalData();
            InitialVitalCtrlList();
        }

        public override void Refresh()
        {
            InitData();
        }

        public void SetCtrlFocus()
        {
            if (SelectedVitalModel != null)
            {
                bool isBreak = false;
                foreach (var item in VitalCtrlList)
                {
                    if (isBreak) break;
                    foreach (BaseVitalCellCtrl ctrl in item.ItemsSource)
                    {
                        if (ctrl.SelfVital.Id.Equals(SelectedVitalModel.Id))
                        {
                            ctrl.SetFocus();
                            isBreak = true;
                            break;
                        }
                    }
                }
            }
        }

        public void RefershDataFromCache()
        {
            InitVitalData();
        }


        #endregion


        #region EventHandlers

        private void Ctrl_GotFocus(object sender, RoutedEventArgs e)
        {
            BaseVitalCellCtrl ctrl = sender as BaseVitalCellCtrl;
            SetParamerterCellCtrlValue(ctrl);
        }

        private void Ctrl_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            BaseVitalCellCtrl ctrl = sender as BaseVitalCellCtrl;
            SetParamerterCellCtrlValue(ctrl);
        }



        private void Ctrl_PreviewKeyUp(object sender, KeyEventArgs e)
        {

        }

        private void Ctrl_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            FocusElement = sender as BaseVitalCellCtrl;
            SetCellFocus(e.Key, e);
        }

        #endregion
    }
}
